/**
 *消息机制
 * @author speed
 * @Date 2016/10/20
 */
class NotificationManager {
    private static _instance:NotificationManager;
    private msgFunDic:any = {};
    /* 添加一个正在处理的队列
     * 应对场景队列处理过程中出现添加和移除侦听
     * 目标
     *  1。保证处理的队列不出现丢失，重复回调，
     *  2。保证新增侦听，移除侦听的操作有效性
     */
    private callingArr:Array<NotificationInfo>=[];
    private callingEventName:string="";
    
	public constructor() {
    	if(NotificationManager._instance){
            throw new Error("NotificationManager单例");
    	}
	}
	
	public registerMsg(notiName:string,notiFun:Function,thisObject:any):void{
	    var self = this;
        var isExist = false;
        var callBackArr:Array<NotificationInfo> = self.msgFunDic[notiName] || [];
        var notiInfo: NotificationInfo = new NotificationInfo(notiName,notiFun,thisObject);
        for(var index=0;index<callBackArr.length;index++){
            var tem:NotificationInfo=callBackArr[index];
            if(tem.notiName==notiName&&tem.notiCallBack===notiFun&&tem.thisObject===thisObject){
                isExist = true;
                break;
            }
        }
        if(!isExist){
            if(notiName==self.callingEventName)
                self.callingArr.push(notiInfo) //处理正在通讯的内容（保证添加的侦听都进有效的）
            callBackArr.push(notiInfo)
            self.msgFunDic[notiName] = callBackArr;
        }
	}
	
    public removeMsg(notiName: string,notiFun: Function,thisObject:any):void{
        var self = this;
        var notiInfo:any = new NotificationInfo(notiName,notiFun,thisObject);
        var callBackArr: Array<NotificationInfo> = self.msgFunDic[notiName];

        for(var index=0;index<callBackArr.length;index++){
            var tem:NotificationInfo=callBackArr[index];
            if(tem.notiName==notiName&&tem.notiCallBack===notiFun&&tem.thisObject===thisObject){
                callBackArr.splice(index,1);
                index--;
            }
        }
        //处理正在通讯的内容（保证移除的侦听都进有效的）
        for(var index=0;index<self.callingArr.length;index++){
            var tem:NotificationInfo=self.callingArr[index];
            if(tem.notiName==notiName&&tem.notiCallBack===notiFun&&tem.thisObject===thisObject){
                self.callingArr.splice(index,1);
                index--;
            }
        }
	}
	
    public sendMsg(notiName: string,args?:any):void{
	     var self = this;
         var callBackArr: Array<NotificationInfo> = self.msgFunDic[notiName];
         if(!callBackArr)
            return;
         self.callingArr=callBackArr.slice();//不能让原数据的改变直接影响到循环体内的数据（此场景出现于在事件通知中移除或添加侦听）
         self.callingEventName=notiName;
         while(self.callingArr.length){
             var info=self.callingArr.pop();//不用index以剔除数组改变的影响
             if(info.notiCallBack){
                info.args = args;
                info.notiCallBack.call(info.thisObject,info);
            }
         }
         self.callingEventName="";
	}
	
	public static get instance():NotificationManager{
	    if(!NotificationManager._instance){
	        NotificationManager._instance = new NotificationManager();
	    }
	    return NotificationManager._instance;
	}
}
